package com.utils
{
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundTransform;
	import flash.net.URLRequest;
	
	/**
	 * 音效管理类 
	 * @author Lufu
	 */	
	public class SoundUtil
	{
		private static var _location:String;//路径
		private static var _isLocationPath:Boolean;//本地路径标记
		private static var _name:String;
		private static var soundList:Array = [];//资源池
		//private static var regExpArr:Array = ['http://','http://www.','.com','.cn','.net','.org','.gov'];
		
		private static var soundClass:SoundClass;
		private static var soundVolume:Number = -1;
		
		/**
		 * 注册音效文件夹路径
		 * 默认路径：'assets/music/'
		 */		
		public static function registerLocation(Location:String = 'assets/music'):void{
			_location = Location;
		}
		
		/**
		 * 自定义音效
		 * @param name 文件名加后缀
		 * @param isLocationPath 本地路径标记
		 * @param continuous true 连续创建音效实例,不检查资源池 false 检查资源池
		 * @param loop 循环播放
		 * @param true:本地路径(默认) false:网络路径
		 */		
		public static function soundPlay(name:String,isLocationPath:Boolean = true,continuous:Boolean = false,loop:Boolean = false,volume:Number = 1):void{
			_name = name;
			
			if(isLocationPath){
				_isLocationPath = isLocationPath;
				if(!_location) throw Error('调用"registerLocation()"注册音效文件夹路径');
			}else{
				_isLocationPath = isLocationPath;
			}
			
			if(checkIsExist(_name) && !continuous){
				//trace('音效已存在，且正在播放！')
				return;//资源池中已有就不再创建实例
			}
			
			var soundClass:SoundClass = new SoundClass();
			soundClass.name = _name;
			soundClass.location = _location;
			soundClass.loop = loop;
			soundClass.isLocationPath = _isLocationPath;
			soundClass.delPlayOverSound = delPlayOverSound; 
			soundClass.volume = soundVolume == -1 ? volume : soundVolume;
			soundList.push(soundClass);
			soundClass.play();
		}
		
		public static function changeAllVolume(value:Number = -1):void{
			soundVolume = value;
			for (var i:int = 0; i < soundList.length; i++) 
			{
				soundList[i].volume = soundVolume;
			}
		}
		
		public static function volume(name:String,volume:Number = 1):void{
			for (var i:int = 0; i < soundList.length; i++) 
			{
				if(soundList[i].name == name){
					soundList[i].volume = volume;
					trace('调整<'+name+'>音量为:' + volume);
				}
			}
		}
		
		/**检查是否是本地路径*/		
		//private static function checkLocationPath():Boolean
		//{
		//var num:int = 0;
		//for (var i:int = 0; i < regExpArr.length; i++) 
		//{
		//var regExp:RegExp =  new RegExp(regExpArr[i]);//正则表达式匹配子符
		//if(regExp.test(_name)) num++;
		//}
		//if(num >= 2){//< http://  .com/.cn/.net/.org/.gov > 同时存在方为网络路径
		//trace('网络音乐:' + _name);
		//return false;
		//}
		//trace('本地音乐:' + _name);
		//return true;
		//}
		
		/**
		 * 检查目标是否在资源池中
		 */		
		private static function checkIsExist(name:String):Boolean
		{
			for (var i:int = 0; i < soundList.length; i++) 
			{
				if(soundList[i].name == name) return true;
			}
			
			return false;
		}
		
		/**
		 * 停止播放音效
		 * @param name 要停止的音效名称<默认停止所有音效>
		 */		
		public static function stopSoundPlay(name:String = 'stopAll'):void{
			
			for (var i:int = 0; i < soundList.length; i++) 
			{
				soundClass = soundList[i];
				
				if(name == 'stopAll'){
					changeSoundState();//执行length次
				}else if(name == soundClass.name){
					changeSoundState();//执行1次
				}
			}
			
			delPlayOverSound();
		}
		
		private static function changeSoundState():void{
			soundClass.stop();
			soundClass.isPlayOver = true;
		}
		
		/**从资源池删除已播放完毕的音效*/		
		private static function delPlayOverSound():void
		{
			var tempList:Array = [];
			for (var i:int = 0; i < soundList.length; i++) 
			{
				if(soundList[i].isPlayOver){
					soundList[i] = null;
					continue;
				}
				tempList.push(soundList[i]);
			}
			soundList = tempList;
		}
		
		
		
		
		
		
		
	}
}

import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundTransform;
import flash.net.URLRequest;

class SoundClass{
	private var _sound:Sound;
	
	private var _soundChanel:SoundChannel;//音轨
	
	private var _path:String;//路径
	
	private var _delPlayOverSound:Function = new Function();//回调函数
	
	public var location:String;//路径
	
	public var name:String;//名字
	
	public var isPlayOver:Boolean;//播放完毕标记
	
	public var isLocationPath:Boolean;//本地路径标记
	
	public var loop:Boolean;
	
	private var _volume:Number = 1;
	
	private var _soundTransFormal:SoundTransform = new SoundTransform();
	
	public function set delPlayOverSound(value:Function):void{_delPlayOverSound = value;}
	
	public function SoundClass(){
		
	}
	
	/**
	 * 自定义音效
	 * @param name 文件名加后缀
	 */		
	public function play():void{
		
		isLocationPath ? _path = location + '/' + name : _path = name;
		
		_sound = new Sound();
		
		_sound.load(new URLRequest(_path));
		
		_sound.addEventListener(IOErrorEvent.IO_ERROR,onErrorHandler);
		
		_soundChanel = _sound.play(); 
		
		setVolume();
		
		if(_soundChanel) _soundChanel.addEventListener(Event.SOUND_COMPLETE,onSoundCompleteHandler);
	}
	
	public function set volume(value:Number):void
	{
		_volume = value;
		setVolume();
	}
	
	
	private function setVolume():void{
		_soundTransFormal.volume = _volume;
		if(_soundChanel) _soundChanel.soundTransform = _soundTransFormal;
	}
	
	private function onErrorHandler(e:IOErrorEvent):void
	{
		throw Error('文件加载出错,错误原因:' + e);
	}
	
	private function onSoundCompleteHandler(e:Event):void{
		if(loop){
			play();
		}else{
			
			isPlayOver = true; 
			
			_delPlayOverSound();
			
			clear();
			
		}
	}
	
	/**停止自定义音效*/
	public function stop():void{
		
		if(_soundChanel){
			
			_soundChanel.stop();
			
			clear();
		}
	}
	
	//清除侦听,滞空对象
	private function clear():void{
		if(_soundChanel.hasEventListener(Event.SOUND_COMPLETE)){
			_soundChanel.removeEventListener(Event.SOUND_COMPLETE,onSoundCompleteHandler);
		}
		
		if(_sound.hasEventListener(IOErrorEvent.IO_ERROR)){
			_sound.removeEventListener(IOErrorEvent.IO_ERROR,onErrorHandler);
		}
		
		_sound = null;
		
		_soundChanel = null;
	}
	
	
	
	
}